//
//  EZAutoreleasePoolManager.cpp
//  zhaitu
//
//  Created by ellzu on 13-8-5.
//  Copyright (c) 2013年 ellzu. All rights reserved.
//

#include "EZAutoreleasePoolManager.h"

using namespace EZTally;


EZAutoreleasePoolManager::EZAutoreleasePoolManager()
{
//    poolsDic = new EZTallyDictionary<long, EZTallyArray<EZAutoreleasePool*>* >();
}

EZAutoreleasePoolManager::~EZAutoreleasePoolManager()
{
    //..... ....//
    
}

EZAutoreleasePoolManager* EZAutoreleasePoolManager::DefaultManager()
{
    static EZAutoreleasePoolManager *manager = NULL;
    if (manager == NULL) {
        manager = new EZAutoreleasePoolManager();
    }
    return manager;
}

EZAutoreleasePool* EZAutoreleasePoolManager::CurrentPool()
{
    std::vector<EZAutoreleasePool*> *pools = PoolsWithThread();
    EZAutoreleasePool *pool = 0;
    if (pools && pools->size()>0) {
        pool = pools->at(pools->size()-1);
    }
    return pool;
}

std::vector<EZAutoreleasePool*>* EZAutoreleasePoolManager::PoolsWithThread(pthread_t thread_)
{
    pthread_t thread = thread_;
    if (thread == 0) {
        thread = pthread_self();
    }
    long threadId = thread->__sig;
//    if (poolsDic->isHasValue(threadId)==false) {
//        return 0;
//    }
    if (poolsDic.find(threadId)==poolsDic.end()) {
        return 0;
    }
    return poolsDic[threadId];

}

void EZAutoreleasePoolManager::AddCurrentThreadPool(EZAutoreleasePool* pool)
{
    AddPoolToThread(pool, pthread_self() );
}
void EZAutoreleasePoolManager::AddPoolToThread(EZAutoreleasePool* pool,pthread_t thread_)
{
    pthread_t thread = thread_;
    if (thread == 0) {
        thread = pthread_self();
    }
    long threadId = thread->__sig;
    std::vector<EZAutoreleasePool*> *pools = PoolsWithThread(thread);
    if (pools==0) {
        pools = new std::vector<EZAutoreleasePool*>();
        poolsDic[threadId] = pools;
    }
//    pools->AddObject(pool);
    pools->push_back(pool);
}

void EZAutoreleasePoolManager::RemovePool(EZAutoreleasePool* pool,pthread_t thread_)
{
    
    pthread_t thread = thread_;
    if (thread == 0) {
        thread = pthread_self();
    }
    long threadId = thread->__sig;
    
    
    if ( poolsDic.find(threadId)!=poolsDic.end()) {
        std::vector<EZAutoreleasePool*> *firstPools = poolsDic[threadId];
        if (RemovePoolOnPools(firstPools, pool)==true) {
            int count = firstPools->size();
            if (count==0) {
                poolsDic.erase( poolsDic.find(threadId) );
            }
            return;
        }
    }
    //上面指定的线程没找到，全局去找
    
    std::map<long, std::vector<EZAutoreleasePool*>* >::iterator it = poolsDic.begin();
    for (; it!=poolsDic.end(); it++) { //遍历所有不同线程的pools
        std::vector<EZAutoreleasePool*> *pools = it->second;
        if (RemovePoolOnPools(pools, pool)) {
            if (pools->size()==0) {
                poolsDic.erase(it);
            }
            break;
        }
    }
}

bool EZAutoreleasePoolManager::RemovePoolOnPools(std::vector<EZAutoreleasePool*> *pools,EZAutoreleasePool *pool)
{
    bool isRemove = false;
    for (int i=0; i<(int)pools->size(); i++) {
        EZAutoreleasePool *fpool = pools->at(i);
        if (fpool == pool) {
            pools->erase(pools->begin()+i);
            isRemove = true;
            break;
        }
    }
    return isRemove;
}

